package com.tedu.api.io;

import org.junit.Test;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Random;

/**
 *  RandomAccessFile 解决：File无法实现读写操作
 *  RandomAccessFile类   随机访问文件类
 *  功能：实现”文件“,文件夹的读写操作，底层使用C语言，底层：二进制数据
 *
 *  创建随机访问文件类
 *  RandomAccessFile   raf=new RandomAccessFile(“路径+文件名称”,"rw")
 *  RandomAccessFile   raf=new RandomAccessFile(“路径+文件名称”,"r")
 *  第二个参数【mode 模式】：r模式--->该文件可以读操作
 *                       rw模式-->该文件可以读写操作
 *
 *  需求：实现CV 复制音乐/视频
 */
public class RandomAccessFileAPI {
    @Test
    public void testRAF() throws IOException {
        //RandomAccessFile对象创建出来--路径+全称 |  模式：”rw“

        RandomAccessFile  raf=new RandomAccessFile("raf.txt","rw");
        //1.在API项目文件夹下 创建 raf.txt 文件，并且实现读写操作

        //计算机 识别：二进制  0000 0000
        /**
         * 需要往raf.txt写出一个 a 字母
         * write(整数：十进制) 十进制 转换为计算机识别二进制
         *       范围：0~255   ASCII码  二进制 ---十进制---字母
         *                                      97      a
         *                                      98      b
         * 作用：往文件中写出一个字节，抛出IO异常流：存在写出失败情况
         *      整数的低八位写出到文件中
         *
         *      1字节==8位二进制     0000 0001     1
         *                         0000 0010     2
         *                         0000 0011     3
         *                         0000 0110     6
         *     1024字节==1KB
         *     1024KB==1MB
         *     1024MB==1G
         *     1024G==1T
         *
         *
         */
        raf.write(97);     //写出：一个字节，识别二进制，写十进制转二进制
        raf.write(98);
        raf.write(101);
        //write方法---一个字节写出
        //关闭流   close()
       raf.close();

    }

    /**
     * read()
     * 作用：读取一个字节，返回十进制int类型返回，如果文件读到-1，代表结束
     *
     */
    @Test
    public void testRead() throws IOException {
        //创建对象：随机访问文件对象---只读---raf.txt文件的内容
        RandomAccessFile raf=
                new RandomAccessFile("raf.txt","r");
        int i= raf.read();   //"a" ---ASCII码---97
        int j= raf.read();
        int k= raf.read();
        int y= raf.read();
        System.out.println(i+" "+j+" "+k+" "+y);
    }

    /**
     * RAF类---构造器实现：读写操作---write(数值)  一个字节一个字节写出以及读入
     * 需求：复制粘贴一个音乐 【version 1--不考虑效率】
     */
    @Test
    public void testCV() throws IOException {
        //1.源文件--“小跳蛙.mp3”--复制--  操作：读入
        RandomAccessFile src=new RandomAccessFile("小跳蛙.mp3","r");
        //2.复制文件-“新跳蛙.mp3”--粘贴-- 操作：写出

        RandomAccessFile desc=new RandomAccessFile("新跳蛙.mp3","rw");
        //3.用于保存读取到的字节：①保存一个字节
       //                    ②-1代表文件读取到末尾
       int date=-1;
       //4.一直从“小跳蛙.mp3”中一个字节一个字节读取---
      // 同时一个字节一个字节写出“新跳蛙”
     //   src.read()       条件判断语句
       long start=System.currentTimeMillis();
        while((date= src.read())!=-1){
            desc.write(date);
        }
       long end=System.currentTimeMillis();
        System.out.println("复制粘贴花费多少："+(end-start)+"毫秒");
    }
    /**
     * 需求：复制粘贴一个音乐【version---考虑效率】
     * 一个字节一个字节读取---【慢】
     * 100KB读取--写出【快】
     *
     */
    @Test
    public void testCVS() throws IOException {
        //1.从“小跳蛙.mp3”--读取数据【100KB】
        RandomAccessFile src = new RandomAccessFile("小跳蛙.mp3", "r");
        //2.从API目录下写出“效率高.mp3”---写出数据【100KB】
        RandomAccessFile desc = new RandomAccessFile("小跳蛙.mp3", "rw");
        //3.保存每次读取字节量：①覆盖：保存读写覆盖，保障数据稳定
        //                  ②没有数据：表示文件读取到末尾
        int len = -1;
        //4.效率：100KB        字节数组：byte
        byte[] data = new byte[1024 * 100]; //100KB
        //5.一直   从src文件中读取数据：100KB  | read(byte[] b)  读100KB
        // 5.1 src.read()    从src"小跳蛙.mp3"   一个字节一个字节读
        // 5.2 src.read(byte[] data)  从src"小跳蛙.mp3"   100KB的读
        // 5.3 len=src.read(byte[] data)
        // 5.4 (len=src.read(byte[] data))!=-1   【复制判断条件】
        //     将读到的100KB的字节数据保存len中，只要不等于-1，没有读完，一直读
        long start = System.currentTimeMillis();


        while ((len = src.read(data)) != -1) {
            //同时 读,取文件
            //write(整数) 写出一个字节【慢】
            //write(字节数组) 写出字节数组指定的单位量【例如：100KB】
            desc.write(data, 0, len);


        }
        long end = System.currentTimeMillis();
        System.out.println("100KB复制版本："+(end-start)+"毫秒数");
    }
    @Test
    public void testCV2()throws IOException{
        RandomAccessFile src = new RandomAccessFile("复制视频.mp4", "r");
        RandomAccessFile desc = new RandomAccessFile("复制视频.mp4", "rw");
        int len = -1;
        byte[] data = new byte[1024 * 100];
        long start = System.currentTimeMillis();
        while ((len = src.read(data)) != -1) {
            //同时 读,取文件
            //write(整数) 写出一个字节【慢】
            //write(字节数组) 写出字节数组指定的单位量【例如：100KB】
            desc.write(data, 0, len);
        }
        long end = System.currentTimeMillis();
        System.out.println("测试2‘："+(end-start)+"毫秒数");
    }
}

